package com.dfh.fabric.demo;

import org.hyperledger.fabric.sdk.*;
import org.hyperledger.fabric.sdk.exception.*;
import org.hyperledger.fabric_ca.sdk.exception.EnrollmentException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class SdkMain {

	private static final Logger log = LoggerFactory.getLogger(SdkMain.class);
	//org1
	private static final String admin1KeyFolderPath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/keystore";
	private static final String admin1KeyFile = "4b5939042e092d1610d883294984d7cc4ca6e1ca495a7307625270be3523c0fd_sk";
	private static final String admin1CertsFolderPath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/peerOrganizations/org1.example.com/users/Admin@org1.example.com/msp/admincerts";
	private static final String admin1CertsFile = "Admin@org1.example.com-cert.pem";
	//org2
	private static final String admin2KeyFolderPath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/keystore";
	private static final String admin2KeyFile = "cd7b9cfb2fb498e1c919e5e56369ccd6556aa081d4024b2a051bb60457a97c47_sk";
	private static final String admin2CertsFolderPath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/peerOrganizations/org2.example.com/users/Admin@org2.example.com/msp/admincerts";
	private static final String admin2CertsFile = "Admin@org2.example.com-cert.pem";

	private static final String orderTlsFilePath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/ordererOrganizations/example.com/tlsca/tlsca.example.com-cert.pem";
	private static final String org1Peer0TlsFilePath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/peerOrganizations/org1.example.com/peers/peer0.org1.example.com/tls/ca.crt";
	private static final String org1Peer1TlsFilePath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/peerOrganizations/org1.example.com/peers/peer1.org1.example.com/tls/ca.crt";

	private static final String org2Peer0TlsFilePath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/peerOrganizations/org2.example.com/peers/peer0.org2.example.com/tls/ca.crt";
	private static final String org2Peer1TlsFilePath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/crypto-config/peerOrganizations/org2.example.com/peers/peer1.org2.example.com/tls/ca.crt";








	//创建channel
	public static void testCreateChannel() throws InvalidKeySpecException, NoSuchAlgorithmException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, TransactionException, ProposalException, org.bouncycastle.crypto.CryptoException {
		String txfilePath = "/Users/dengfaheng/Github/Fabric1.4.0-java-sdk-demo/src/main/resources/test1.tx";
		UserContext userContext = new UserContext();
		userContext.setAffiliation("Org1");
		userContext.setMspId("Org1MSP");
		userContext.setAccount("李伟");
		userContext.setName("admin");
		Enrollment enrollment = UserUtils.getEnrollment(admin1KeyFolderPath, admin1KeyFile, admin1CertsFolderPath, admin1CertsFile);
		userContext.setEnrollment(enrollment);
		FabricClient fabricClient = new FabricClient(userContext);
        /*
        //获取存在的channel
        Channel channel = fabricClient.getChannel("test1");
        channel.addOrderer(fabricClient.getOrderer("orderer.example.com","grpcs://orderer.example.com:7050",orderTlsFilePath));
        channel.joinPeer(fabricClient.getPeer("peer0.org1.example.com","grpcs://peer0.org1.example.com:7051",peer0TlsFilePath));
        channel.initialize();

         */
		//创建channel，一般创建完成后就要加入某个peer。
		Channel channel = fabricClient.createChannel("test1", fabricClient.getOrderer("orderer.example.com", "grpcs://orderer.example.com:7050", orderTlsFilePath), txfilePath);
		channel.addOrderer(fabricClient.getOrderer("orderer.example.com", "grpcs://orderer.example.com:7050", orderTlsFilePath));
		channel.joinPeer(fabricClient.getPeer("peer0.org1.example.com", "grpcs://peer0.org1.example.com:7051", org1Peer0TlsFilePath));
	}

	//安装合约
	public static void installContract() throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, TransactionException, ProposalException, org.bouncycastle.crypto.CryptoException {
		UserContext userContext = new UserContext();
		userContext.setAffiliation("Org2");
		userContext.setMspId("Org2MSP");
		userContext.setAccount("李伟");
		userContext.setName("admin");
		Enrollment enrollment = UserUtils.getEnrollment(admin2KeyFolderPath, admin2KeyFile, admin2CertsFolderPath, admin2CertsFile);
		userContext.setEnrollment(enrollment);
		FabricClient fabricClient = new FabricClient(userContext);
		Peer peer0 = fabricClient.getPeer("peer0.org2.example.com", "grpcs://peer0.org2.example.com:9051", org2Peer0TlsFilePath);
		Peer peer1 = fabricClient.getPeer("peer1.org2.example.com", "grpcs://peer1.org2.example.com:10051", org2Peer1TlsFilePath);
		List<Peer> peers = new ArrayList<>();
		peers.add(peer0);
		peers.add(peer1);
		fabricClient.installChaincode(TransactionRequest.Type.GO_LANG, "basicinfo", "2.0", "chaincode", "basicinfo", peers);
	}

	//合约实例化
	public static void initContract() throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, ProposalException, TransactionException, org.bouncycastle.crypto.CryptoException {
		UserContext userContext = new UserContext();
		userContext.setAffiliation("Org2");
		userContext.setMspId("Org2MSP");
		userContext.setAccount("李伟");
		userContext.setName("admin");
		Enrollment enrollment = UserUtils.getEnrollment(admin2KeyFolderPath, admin2KeyFile, admin2CertsFolderPath, admin2CertsFile);
		userContext.setEnrollment(enrollment);
		FabricClient fabricClient = new FabricClient(userContext);
		Peer peer = fabricClient.getPeer("peer0.org2.example.com", "grpcs://peer0.org2.example.com:9051", org2Peer0TlsFilePath);
		Orderer order = fabricClient.getOrderer("orderer.example.com", "grpcs://orderer.example.com:7050", orderTlsFilePath);
		String[] initArgs = {""};
		fabricClient.initChaincode("mychannel", TransactionRequest.Type.GO_LANG, "basicinfo", "2.0", order, peer, "init", initArgs);
	}

	//合约升级
	public static void upgradeContract() throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, ProposalException, TransactionException, ChaincodeEndorsementPolicyParseException, org.bouncycastle.crypto.CryptoException {
		UserContext userContext = new UserContext();
		userContext.setAffiliation("Org2");
		userContext.setMspId("Org2MSP");
		userContext.setAccount("李伟");
		userContext.setName("admin");
		Enrollment enrollment = UserUtils.getEnrollment(admin2KeyFolderPath, admin2KeyFile, admin2CertsFolderPath, admin2CertsFile);
		userContext.setEnrollment(enrollment);
		FabricClient fabricClient = new FabricClient(userContext);
		Peer peer = fabricClient.getPeer("peer0.org2.example.com", "grpcs://peer0.org2.example.com:9051", org2Peer0TlsFilePath);
		Orderer order = fabricClient.getOrderer("orderer.example.com", "grpcs://orderer.example.com:7050", orderTlsFilePath);
		String[] initArgs = {""};
		fabricClient.upgradeChaincode("mychannel", TransactionRequest.Type.GO_LANG, "basicinfo", "2.0", order, peer, "init", initArgs);
	}

	//invoke 合约
	public static void invokeContract() throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, ProposalException, TransactionException, ChaincodeEndorsementPolicyParseException, org.bouncycastle.crypto.CryptoException {
		UserContext userContext = new UserContext();
		userContext.setAffiliation("Org1");
		userContext.setMspId("Org1MSP");
		userContext.setAccount("李伟");
		userContext.setName("admin");
		Enrollment enrollment = UserUtils.getEnrollment(admin1KeyFolderPath, admin1KeyFile, admin1CertsFolderPath, admin1CertsFile);
		userContext.setEnrollment(enrollment);
		FabricClient fabricClient = new FabricClient(userContext);
		Peer peer0 = fabricClient.getPeer("peer0.org1.example.com", "grpcs://peer0.org1.example.com:7051", org1Peer0TlsFilePath);
		Peer peer1 = fabricClient.getPeer("peer0.org2.example.com", "grpcs://peer0.org2.example.com:9051", org2Peer0TlsFilePath);
		List<Peer> peers = new ArrayList<>();
		peers.add(peer0);
		peers.add(peer1);
		Orderer order = fabricClient.getOrderer("orderer.example.com", "grpcs://orderer.example.com:7050", orderTlsFilePath);
		String[] initArgs = {"11", "{\"name\":\"zhangsan\",\"identity\":\"11\",\"mobile\":\"18910012222\"}"};
		fabricClient.invoke("mychannel", TransactionRequest.Type.GO_LANG, "basicinfo", order, peers, "save", initArgs);
	}

	//查询合约
	public static void queryContract() throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, ProposalException, TransactionException, org.bouncycastle.crypto.CryptoException {
		UserContext userContext = new UserContext();
		userContext.setAffiliation("Org2");
		userContext.setMspId("Org2MSP");
		userContext.setAccount("李伟");
		userContext.setName("admin");
		Enrollment enrollment = UserUtils.getEnrollment(admin2KeyFolderPath, admin2KeyFile, admin2CertsFolderPath, admin2CertsFile);
		userContext.setEnrollment(enrollment);
		FabricClient fabricClient = new FabricClient(userContext);
		Peer peer0 = fabricClient.getPeer("peer0.org1.example.com", "grpcs://peer0.org1.example.com:7051", org1Peer0TlsFilePath);
		Peer peer1 = fabricClient.getPeer("peer0.org2.example.com", "grpcs://peer0.org2.example.com:9051", org2Peer0TlsFilePath);
		List<Peer> peers = new ArrayList<>();
		peers.add(peer0);
		peers.add(peer1);
		String[] initArgs = {"11"};
		Map map = fabricClient.queryChaincode(peers, "mychannel", TransactionRequest.Type.GO_LANG, "basicinfo", "query", initArgs);
		System.out.println(map);
	}

	//注册用户 QFHZMyIpOnar
	public static void registerUser() throws Exception {
		FabricCAClient caClient = new FabricCAClient("http://172.16.46.3", null);
		UserContext register = new UserContext();
		register.setName("lihua");
		register.setAffiliation("org2");
		Enrollment enrollment = caClient.enroll("admin", "adminpw");
		UserContext registar = new UserContext();
		registar.setName("admin");
		registar.setAffiliation("org2");
		registar.setEnrollment(enrollment);
		String secret = caClient.register(registar, register);
		System.out.println(secret);
	}


    //注册用户查询合约
    public static void UserQueryContract() throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, CryptoException, ProposalException, TransactionException, org.bouncycastle.crypto.CryptoException, EnrollmentException, org.hyperledger.fabric_ca.sdk.exception.InvalidArgumentException, EnrollmentException {
        FabricCAClient caClient = new FabricCAClient("http://172.16.46.3",null);
        UserContext userContext = new UserContext();
        userContext.setAffiliation("Org2");
        userContext.setMspId("Org2MSP");
        userContext.setAccount("李伟");
        userContext.setName("admi11n");
        Enrollment enrollment = caClient.enroll("lihua","QFHZMyIpOnar");
        userContext.setEnrollment(enrollment);
        FabricClient fabricClient = new FabricClient(userContext);
        Peer peer0 = fabricClient.getPeer("peer0.org1.example.com","grpcs://peer0.org1.example.com:7051",org1Peer0TlsFilePath);
        Peer peer1 = fabricClient.getPeer("peer0.org2.example.com","grpcs://peer0.org2.example.com:9051",org2Peer0TlsFilePath);
        List<Peer> peers = new ArrayList<>();
        peers.add(peer0);
        peers.add(peer1);
        String[] initArgs = {"12"};
        Map map =  fabricClient.queryChaincode(peers,"mychannel", TransactionRequest.Type.GO_LANG,"basicinfo","query",initArgs);
        System.out.println(map);
    }

	//注册用户invoke合约
    public static void userInvokeContract() throws InvalidKeySpecException, NoSuchAlgorithmException, CryptoException, IOException, IllegalAccessException, InvalidArgumentException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, org.hyperledger.fabric.sdk.exception.CryptoException, ProposalException, TransactionException, ChaincodeEndorsementPolicyParseException, EnrollmentException, org.hyperledger.fabric_ca.sdk.exception.InvalidArgumentException {
        FabricCAClient caClient = new FabricCAClient("http://172.16.46.3",null);
        UserContext userContext = new UserContext();
        userContext.setAffiliation("Org2");
        userContext.setMspId("Org2MSP");
        userContext.setAccount("李伟");
        userContext.setName("admin");
        Enrollment enrollment = caClient.enroll("lihua","QFHZMyIpOnar");
        userContext.setEnrollment(enrollment);
        FabricClient fabricClient = new FabricClient(userContext);
        Peer peer0 = fabricClient.getPeer("peer0.org1.example.com","grpcs://peer0.org1.example.com:7051",org1Peer0TlsFilePath);
        Peer peer1 = fabricClient.getPeer("peer0.org2.example.com","grpcs://peer0.org2.example.com:9051",org2Peer0TlsFilePath);
        List<Peer> peers = new ArrayList<>();
        peers.add(peer0);
        peers.add(peer1);
        Orderer order = fabricClient.getOrderer("orderer.example.com","grpcs://orderer.example.com:7050",orderTlsFilePath);
        String[] initArgs = {"12","{\"name\":\"zhangsan\",\"identity\":\"12\",\"mobile\":\"18910012222\"}"};
        fabricClient.invoke("mychannel", TransactionRequest.Type.GO_LANG,"basicinfo",order,peers,"save",initArgs);
    }

	public static void main(String[] args) throws Exception {
		//testCreateChannel();
		//installContract();
		//initContract();
		//upgradeContract();
		//invokeContract();
		//queryContract();
        //registerUser();
		UserQueryContract();
		//userInvokeContract();
	}
}
